/**
 * Title : jFamilyTree
 * Description: jFamilyTree
 * About: Designed and rewritten by Andreas Lundgren, based on the Treebolic application suite
 * Copyright:	(c) 2001-2008
 * Terms of use:see license agreement at http://treebolic.sourceforge.net/en/license.htm
 * Author: Bernard Bou
 * Company: bsys
 */
package jFamilyTree.generator;

import java.awt.Color;
import java.awt.Component;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.util.Map;
import java.util.SortedSet;
import java.util.Vector;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableColumn;

import jFamilyTree.Messages;
import jFamilyTree.commons.Utils;

/**
 * Reference list dialog
 * 
 * @author Bernard Bou
 */
public class ReferenceListDialog extends JDialog
{
	private static final long serialVersionUID = 1L;

	/**
	 * Controller
	 */
	protected final Controller theController;

	// C O M P O N E N T S

	/**
	 * Label
	 */
	protected JLabel theLabel;

	/**
	 * Reference table
	 */
	protected JTable theReferenceTable;

	/**
	 * Reference table scrollpane
	 */
	protected JScrollPane theScrollPane;

	/**
	 * Button panel
	 */
	protected JPanel theButtonPanel;

	// C O N S T R U C T O R

	/**
	 * Constructor
	 */
	public ReferenceListDialog(Controller thisController)
	{
		super();
		theController = thisController;
		initialize();
	}

	/**
	 * Initialize
	 */
	private void initialize()
	{
		setResizable(true);

		// label
		theLabel = new JLabel();

		// reference table
		theReferenceTable = new JTable();
		theReferenceTable.setToolTipText(Messages.getString("ReferenceListDialog.0")); //$NON-NLS-1$

		// update
		update();

		// scroll pane
		theScrollPane = new JScrollPane(theReferenceTable);

		// buttons
		JButton thisUpdateButton = new JButton(Messages.getString("ReferenceListDialog.1")); //$NON-NLS-1$
		thisUpdateButton.addActionListener(new java.awt.event.ActionListener()
		{
			/*
			 * (non-Javadoc)
			 * 
			 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
			 */
			public void actionPerformed(ActionEvent e)
			{
				update();
			}
		});
		JButton thisCancelButton = new JButton(Messages.getString("ReferenceListDialog.2")); //$NON-NLS-1$
		thisCancelButton.addActionListener(new java.awt.event.ActionListener()
		{
			/*
			 * (non-Javadoc)
			 * 
			 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
			 */
			public void actionPerformed(ActionEvent e)
			{
				setVisible(false);
			}
		});

		// button panel
		theButtonPanel = new JPanel();
		theButtonPanel.add(thisCancelButton, null);
		theButtonPanel.add(thisUpdateButton, null);

		// assemble
		JPanel thisPanel = new JPanel();
		thisPanel.setLayout(new GridBagLayout());
		thisPanel.add(theLabel, new GridBagConstraints(0, 0, 1, 1, 0., 0., GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(10, 10, 0, 10), 0, 0));
		thisPanel.add(theScrollPane, new GridBagConstraints(0, 1, 1, 1, 1., 1., GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 10, 5, 10), 0, 0));
		thisPanel.add(theButtonPanel, new GridBagConstraints(0, 2, 1, 1, 0., 0., GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(5, 10, 10, 10), 0, 0));

		setContentPane(thisPanel);
	}

	/**
	 * Update
	 */
	protected void update()
	{
		// renderer
		TableColumn thisImageColumn = theReferenceTable.getColumnModel().getColumn(0);
		thisImageColumn.setWidth(150);
		thisImageColumn.setCellRenderer(new DefaultTableCellRenderer()
		{
			private static final long serialVersionUID = 1L;

			/*
			 * (non-Javadoc)
			 * 
			 * @see javax.swing.table.DefaultTableCellRenderer#getTableCellRendererComponent(javax.swing.JTable, java.lang.Object, boolean, boolean, int, int)
			 */
			@Override
			public Component getTableCellRendererComponent(JTable thisTable, Object thisValue, boolean thisIsSelected, boolean thisHasFocus, int thisRow, int thisColumn)
			{
				ParameterModel.Entry thisEntry = (ParameterModel.Entry) thisValue;
				setText(thisEntry.theKey);
				setBackground(thisEntry.theValueCount > 1 ? Color.PINK : Color.WHITE);
				return this;
			}
		});

		TableColumn thisLocationColumn = theReferenceTable.getColumnModel().getColumn(1);
		thisLocationColumn.setCellRenderer(new DefaultTableCellRenderer()
		{
			private static final long serialVersionUID = 1L;

			/*
			 * (non-Javadoc)
			 * 
			 * @see javax.swing.table.DefaultTableCellRenderer#getTableCellRendererComponent(javax.swing.JTable, java.lang.Object, boolean, boolean, int, int)
			 */
			@Override
			public Component getTableCellRendererComponent(JTable thisTable, Object thisValue, boolean thisIsSelected, boolean thisHasFocus, int thisRow, int thisColumn)
			{
				ParameterModel.Entry thisEntry = (ParameterModel.Entry) thisValue;
				String thisLocation = thisEntry.theValue;
				setText(thisLocation);
				return this;
			}
		});
	}

	/**
	 * Set model
	 * 
	 * @param thisTargetToLocationMap
	 *        target to location map
	 */
	protected void setModel(Map<String, SortedSet<String>> thisTargetToLocationMap)
	{
		theReferenceTable.setModel(new ParameterModel(thisTargetToLocationMap));

		// renderer
		TableColumn thisTargetColumn = theReferenceTable.getColumnModel().getColumn(0);
		thisTargetColumn.setWidth(150);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.awt.Dialog#setVisible(boolean)
	 */
	public void setVisible(boolean thisFlag)
	{
		if (thisFlag)
		{
			pack();
			Utils.center(this);
		}
		super.setVisible(thisFlag);
	}

	// M O D E L

	/**
	 * Parameter model
	 * 
	 * @author Bernard Bou
	 */
	protected class ParameterModel extends AbstractTableModel
	{
		/**
		 * Serial version uid
		 */
		private static final long serialVersionUID = 1L;

		/**
		 * Properties
		 */
		private Vector<Entry> theEntries = new Vector<Entry>();

		class Entry
		{
			/**
			 * Key
			 */
			public String theKey;

			/**
			 * Value
			 */
			public String theValue;

			/**
			 * Number of values for key
			 */
			public int theValueCount;

			/**
			 * Constructor
			 * 
			 * @param thisKey
			 *        key
			 * @param thisValue
			 *        value
			 */
			public Entry(String thisKey, String thisValue, int thisValueCount)
			{
				theKey = thisKey;
				theValue = thisValue;
				theValueCount = thisValueCount;
			}
		}

		/**
		 * Parameter model
		 * 
		 * @param thisTargetToLocationMap
		 *        target location map
		 */
		public ParameterModel(Map<String, SortedSet<String>> thisTargetToLocationMap)
		{
			if (thisTargetToLocationMap == null)
				return;

			for (String thisTarget : thisTargetToLocationMap.keySet())
			{
				SortedSet<String> theseLocations = thisTargetToLocationMap.get(thisTarget);
				int thisCount = theseLocations.size();
				for (String thisLocation : theseLocations)
					newRow(new ParameterModel.Entry(thisTarget, thisLocation, thisCount));
			}
		}

		/**
		 * New row
		 * 
		 * @param thisEntry
		 *        entry
		 * @return row index
		 */
		public int newRow(Entry thisEntry)
		{
			theEntries.add(thisEntry);
			int thisRowIdx = theEntries.size() - 1;
			this.fireTableRowsInserted(thisRowIdx, thisRowIdx);
			return thisRowIdx;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see javax.swing.table.TableModel#getRowCount()
		 */
		public int getRowCount()
		{
			return theEntries.size();
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see javax.swing.table.TableModel#getColumnCount()
		 */
		public int getColumnCount()
		{
			return 2;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see javax.swing.table.TableModel#isCellEditable(int, int)
		 */
		public boolean isCellEditable(int y, int x)
		{
			return false;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see javax.swing.table.TableModel#getValueAt(int, int)
		 */
		public Object getValueAt(int y, int x)
		{
			return theEntries.get(y);
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see javax.swing.table.TableModel#getColumnName(int)
		 */
		public String getColumnName(int x)
		{
			switch (x)
			{
			case 0:
				return Messages.getString("ReferenceListDialog.10"); //$NON-NLS-1$
			case 1:
				return Messages.getString("ReferenceListDialog.11"); //$NON-NLS-1$
			default:
				return null;
			}
		}
	}
}
